package http

import (
	"net/url"

	"github.com/gin-gonic/gin"
	"github.com/gin-gonic/gin/binding"
)

type Context struct {
	ctx        *gin.Context
	queryCache url.Values
}

func (ts *Context) Query(key string) string {
	v, _ := ts.GetQuery(key)
	return v
}

func (ts *Context) GetQuery(key string) (string, bool) {
	if values, ok := ts.GetQueryArray(key); ok {
		return values[0], ok
	}
	return "", false
}

func (ts *Context) AllQuery() map[string]string {
	ts.initQueryCache()
	mp := make(map[string]string)
	for k, v := range ts.queryCache {
		mp[k] = v[0]
	}
	return mp
}

func (ts *Context) QueryArray(key string) []string {
	v, _ := ts.GetQueryArray(key)
	return v
}

func (ts *Context) GetQueryArray(key string) (values []string, ok bool) {
	ts.initQueryCache()
	values, ok = ts.queryCache[key]
	return
}

func (ts *Context) AllQueryArray() map[string][]string {
	ts.initQueryCache()
	return ts.queryCache
}

func (ts *Context) ShouldBindQuery(obj any) error {
	return ts.ctx.ShouldBindWith(obj, binding.Query)
}

func (ts *Context) ShouldBind(obj any) error {
	return ts.ctx.ShouldBind(obj)
}

func (ts *Context) initQueryCache() {
	if ts.queryCache == nil {
		if ts.ctx.Request != nil {
			ts.queryCache = ts.ctx.Request.URL.Query()
		} else {
			ts.queryCache = url.Values{}
		}
	}
}
